#!/bin/sh
################################################################################
# mm_uid
#
# This script provides a unique identifier based on hardware information.
#
# The output has the formats:
#     pci:<class>:<class_prog>:<vendor>:<device>:<subsystem_vendor>:<subsystem_device>:<bus_id>
#     usb:<idVendor>:<idProduct>:<serial>
################################################################################

script='BEGIN
        {
            FS="\n"
            RS=""
            mm_uid=""
            phys=""
            bInterfaceNumber=""
        }
        mm_uid !~ /^$/ { next }
        $1 !~ /^ *looking at / { next }
        {
            x = 1
            subsystem=""
            while ( x < NF ) {
                x++
                if ( $x ~ /^ *SUBSYSTEMS?=="acpi"/ ) {
                    subsystem="acpi"
                    break
                }
                if ( $x ~ /^ *SUBSYSTEMS?=="input"/ ) {
                    subsystem="input"
                    break
                }
                if ( $x ~ /^ *SUBSYSTEMS?=="pci"/ ) {
                    subsystem="pci"
                    break
                }
                if ( $x ~ /^ *SUBSYSTEMS?=="serio"/ ) {
                    subsystem="serio"
                    break
                }
                if ( $x ~ /^ *SUBSYSTEMS?=="usb"/ ) {
                    subsystem="usb"
                    break
                }
            }
            if ( subsystem == "acpi" ) {
                while ( x < NF ) {
                    x++
                }
                if ( phys ) {
                    mm_uid="phys:" phys
                }
            }
            if ( subsystem == "input" ) {
                while ( x < NF ) {
                    x++
                    if ( $x ~ /^ *ATTRS?\{phys\}==/ ) {
                        phys=$x
                        sub(/^ *ATTRS?\{phys\}=="/, "", phys)
                        sub(/"$/, "", phys)
                        gsub(/\//, ":", phys)
                    }
                }
            }
            if ( subsystem == "pci" ) {
                class=""
                class_prog=""
                vendor=""
                device=""
                subsystem_vendor=""
                subsystem_device=""
                bus_id=""
                while ( x < NF ) {
                    x++
                    if ( $x ~ /^ *ATTRS?\{vendor\}==/ ) {
                        vendor=$x
                        sub(/^ *ATTRS?\{vendor\}=="0x/, "", vendor)
                        sub(/"$/, "", vendor)
                    }
                    if ( $x ~ /^ *ATTRS?\{device\}==/ ) {
                        device=$x
                        sub(/^ *ATTRS?\{device\}=="0x/, "", device)
                        sub(/"$/, "", device)
                    }
                    if ( $x ~ /^ *ATTRS?\{subsystem_vendor\}==/ ) {
                        subsystem_vendor=$x
                        sub(/^ *ATTRS?\{subsystem_vendor\}=="0x/, "", subsystem_vendor)
                        sub(/"$/, "", subsystem_vendor)
                    }
                    if ( $x ~ /^ *ATTRS?\{subsystem_device\}==/ ) {
                        subsystem_device=$x
                        sub(/^ *ATTRS?\{subsystem_device\}=="0x/, "", subsystem_device)
                        sub(/"$/, "", subsystem_device)
                    }
                    if ( $x ~ /^ *KERNELS?==/ ) {
                        bus_id=$x
                        sub(/^ *KERNELS=="/, "", bus_id)
                        sub(/"$/, "", bus_id)
                    }
                }
                if ( class && class_prog && vendor && device && subsystem_vendor && subsystem_device && bus_id ) {
                    mm_uid="pci:" class ":" class_prog ":" vendor ":" device ":" subsystem_vendor ":" subsystem_device ":" bus_id
                }
            }
            if ( subsystem == "serio" ) {
                while ( x < NF ) {
                    x++
                }
                if ( phys ) {
                    mm_uid="phys:" phys
                }
            }
            if ( subsystem == "usb" ) {
                idVendor=""
                idProduct=""
                serial=""
                manufacturer=""
                while ( x < NF ) {
                    x++
                    if ( $x ~ /^ *ATTRS?\{idVendor\}==/ ) {
                        idVendor=$x
                        sub(/^ *ATTRS?\{idVendor\}=="/, "", idVendor)
                        sub(/"$/, "", idVendor)
                        if ( idVendor == "0000" ) {
                            idVendor=""
                        }
                    }
                    if ( $x ~ /^ *ATTRS?\{idProduct\}==/ ) {
                        idProduct=$x
                        sub(/^ *ATTRS?\{idProduct\}=="/, "", idProduct)
                        sub(/"$/, "", idProduct)
                        if ( idProduct == "0000" ) {
                            idProduct=""
                        }
                    }
                    if ( $x ~ /^ *ATTRS?\{serial\}==/ ) {
                        serial=$x
                        sub(/^ *ATTRS?\{serial\}=="/, "", serial)
                        sub(/"$/, "", serial)
                    }
                    if ( $x ~ /^ *ATTRS?\{bInterfaceNumber\}==/ ) {
                        bInterfaceNumber=$x
                        sub(/^ *ATTRS?\{bInterfaceNumber\}=="/, "", bInterfaceNumber)
                        sub(/"$/, "", bInterfaceNumber)
                    }
                }
                if ( idVendor && idProduct ) {
                    mm_uid="usb:" idVendor ":" idProduct ":" serial ":" bInterfaceNumber
                }
            }
            if ( mm_uid ) {
                print mm_uid
            }
        }'

/usr/bin/udevadm info --attribute-walk --path ${DEVPATH} | /usr/bin/awk "${script}"

exit 0
